﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace XMouse360
{
	class XMouseApplication
	{
		private NotifyIcon trayIcon;
		private ContextMenu trayMenu;
		private static GamePadEventGenerator eventGen;

		public static Keymap CurrentKeymap;

		public static double CursorPositionX;
		public static double CursorPositionY;
		public static double OldMovement;
		public static DateTime LastMovement;

		public static double OldScrollingX;
		public static double OldScrollingY;
		public static double OldScrollingMagnitude;
		public static DateTime LastScrolling;

		public static bool DebugMessages = false;
		public static bool DebugStickMessages = false;

		public static int RefreshPeriod
		{
			get
			{
				return eventGen.RefreshPeriod;
			}
		}


		public XMouseApplication()
		{
			OldMovement = 0;
			OldScrollingX = 0;
			OldScrollingY = 0;
			LastMovement = DateTime.MinValue;
			LastScrolling = DateTime.MinValue;
			eventGen = new GamePadEventGenerator();


		}


		public void Run()
		{
			if (Properties.Settings.Default.ResetFlag)
			{
				ResetActions();
				Properties.Settings.Default.ResetFlag = false;
			}
			CurrentKeymap = KeymapIO.Load(0);
			eventGen.AButtonPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.AButtonReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.BButtonPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.BButtonReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.XButtonPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.XButtonReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.YButtonPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.YButtonReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.BackButtonPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.BackButtonReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.StartButtonPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.StartButtonReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.LeftShoulderPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.LeftShoulderReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.RightShoulderPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.RightShoulderReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.LeftStickPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.LeftStickReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.RightStickPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.RightStickReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadDownPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadDownReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadUpPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadUpReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadLeftPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadLeftReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadRightPressed += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.DPadRightReleased += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.LeftTriggerPulled += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.RightTriggerPulled += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.LeftStickDisplaced += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.RightStickDisplaced += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.Connected += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.Disconnected += new GamePadEventGenerator.ControllerInputEventHandler(EventRunner);
			eventGen.Run();


		}

		private void EventRunner(object sender, ControllerInputEventArgs e)
		{
			if(XMouseApplication.DebugMessages)
				MessageBox.Show(string.Format("EventRunner: Event={0}", e.Name));
			switch (e.Name)
			{
				case "A":
					foreach (Keymap.Event ev in CurrentKeymap.A)
						ev.GetReader().Execute(e);
					break;
				case "B":
					foreach (Keymap.Event ev in CurrentKeymap.B)
						ev.GetReader().Execute(e);
					break;
				case "X":
					foreach (Keymap.Event ev in CurrentKeymap.X)
						ev.GetReader().Execute(e);
					break;
				case "Y":
					foreach (Keymap.Event ev in CurrentKeymap.Y)
						ev.GetReader().Execute(e);
					break;
				case "Back":
					foreach (Keymap.Event ev in CurrentKeymap.Back)
						ev.GetReader().Execute(e);
					break;
				case "Start":
					foreach (Keymap.Event ev in CurrentKeymap.Start)
						ev.GetReader().Execute(e);
					break;
				case "LeftShoulder":
					foreach (Keymap.Event ev in CurrentKeymap.LeftShoulder)
						ev.GetReader().Execute(e);
					break;
				case "RightShoulder":
					foreach (Keymap.Event ev in CurrentKeymap.RightShoulder)
						ev.GetReader().Execute(e);
					break;
				case "DPadUp":
					foreach (Keymap.Event ev in CurrentKeymap.DPadUp)
						ev.GetReader().Execute(e);
					break;
				case "DPadDown":
					foreach (Keymap.Event ev in CurrentKeymap.DPadDown)
						ev.GetReader().Execute(e);
					break;
				case "DPadLeft":
					foreach (Keymap.Event ev in CurrentKeymap.DPadLeft)
						ev.GetReader().Execute(e);
					break;
				case "DPadRight":
					foreach (Keymap.Event ev in CurrentKeymap.DPadRight)
						ev.GetReader().Execute(e);
					break;
				case "LeftStickButton":
					foreach (Keymap.Event ev in CurrentKeymap.LeftStickPress)
						ev.GetReader().Execute(e);
					break;
				case "RightStickButton":
					foreach (Keymap.Event ev in CurrentKeymap.RightStickPress)
						ev.GetReader().Execute(e);
					break;
				case "LeftTrigger":
					foreach (Keymap.Event ev in CurrentKeymap.LeftTrigger)
						ev.GetReader().Execute(e);
					break;
				case "RightTrigger":
					foreach (Keymap.Event ev in CurrentKeymap.RightTrigger)
						ev.GetReader().Execute(e);
					break;
				case "LeftStick":
					foreach (Keymap.Event ev in CurrentKeymap.LeftStick)
						ev.GetReader().Execute(e);
					break;
				case "RightStick":
					foreach (Keymap.Event ev in CurrentKeymap.RightStick)
						ev.GetReader().Execute(e);
					break;
				case "IsConnected":
					foreach (Keymap.Event ev in CurrentKeymap.Connected)
						ev.GetReader().Execute(e);
					break;
				default: throw new FormatException("Unrecognized Keymap Event");
			}
		}

		private void ExitClick(object sender, EventArgs e)
		{

		}

		void createTrayIcon()
		{
			trayIcon = new NotifyIcon();
			trayIcon.Text = "XMouse360";
			trayMenu = new ContextMenu();
			trayIcon.ContextMenu = trayMenu;



			trayMenu.MenuItems.Add(new MenuItem("Exit", ExitClick));
		}



		void ResetActions()
		{

			Properties.Settings.Default.DefaultDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + @"\My Keymaps";
			System.IO.Directory.CreateDirectory(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + @"\My Keymaps");
			Keymap DefaultMouse;



			DefaultMouse = new Keymap
			{
				rank = 0,
				Name = "DefaultMouse",
				IsDefault = true,
				A = new List<Keymap.Event>
				{
					new Keymap.Event
					{
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_LEFTDOWN),
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						IsBoolean = true,
						EventTime = EventTrigger.OnPress,
						Direction = KeyDirection.Down
						
						
					},
					new Keymap.Event
					{
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_LEFTUP),
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						IsBoolean = true,
						EventTime = EventTrigger.OnRelease,
						Direction = KeyDirection.Up
					}
				},
				B = new List<Keymap.Event>
				{
					new Keymap.Event
					{
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_RIGHTDOWN),
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						IsBoolean = true,
						EventTime = EventTrigger.OnPress,
						Direction = KeyDirection.Down
						
						
					},
					new Keymap.Event
					{
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_RIGHTUP),
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						IsBoolean = true,
						EventTime = EventTrigger.OnRelease,
						Direction = KeyDirection.Up
					}
				},
				X = new List<Keymap.Event>
				{
					new Keymap.Event
					{
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_MIDDLEDOWN),
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						IsBoolean = true,
						EventTime = EventTrigger.OnPress,
						Direction = KeyDirection.Down
						
						
					},
					new Keymap.Event
					{
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_MIDDLEUP),
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						IsBoolean = true,
						EventTime = EventTrigger.OnRelease,
						Direction = KeyDirection.Up
					}
				},
				LeftStick = new List<Keymap.Event>
				{
					new Keymap.Event
					{
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_MOVE),
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						Acceleration = 5.5f,
						TimeAcceleration = true,
						TimeAccelerationPercent = 98f,
						constant = 2.2f
					}
				},
				RightStick = new List<Keymap.Event>
				{
					new Keymap.Event
					{
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_WHEEL),
						Acceleration = 7f,
						TimeAcceleration = true,
						TimeAccelerationPercent = 99.7f,
						constant = 2.2f
					},
					new Keymap.Event
					{
						Type = InputData.InputTypeToString(InputData.INPUTTYPE.INPUT_MOUSE),
						Code = InputData.MouseEventToString(InputData.MOUSEEVENT.MOUSEEVENTF_HWHEEL),
						Acceleration = 7f,
						TimeAcceleration = true,
						TimeAccelerationPercent = 99.7f,
						constant = 2.2f
					}
				}
			};
			KeymapIO.WriteNewKeymapToDefault(DefaultMouse, "Default Mouse.kmp");


		}
	}


}
